#include"MenuBar.h"
MenuBar::MenuBar()
{}
MenuBar::MenuBar(int no, char **str)
{
	int i;
	NoOfMenus = no;

	for ( i = 0; i < NoOfMenus; i++ )
	{
		Titles[i] = (char *) malloc(STR);
		strcpy(Titles[i], str[i]);
	}
	calculateXY();
}
/****************************************************************************
 *  Name       : calculateXY
 *  Parameters : None
 *  Returns    : Nothing
 *  Purpose    : Initializes the positions of the Menus displayed in the
 *               MenuBar.
 ****************************************************************************/
void MenuBar::calculateXY()
{
	int i;
	x = (int *) malloc(NoOfMenus * sizeof(int));
	y = (int *) malloc(NoOfMenus * sizeof(int));
	x[0] = 1;
	y[0] = 0;
	for ( i = 1; i < NoOfMenus; i++ )
	{
		x[i] = x[i - 1] + strlen(Titles[i - 1]) + 1;
		y[i] = 0;
	}
}
/****************************************************************************
 *  Name       : highlightTitle
 *  Parameters : Index of the Title to be highlighted
 *               Color of the highlight
 *  Returns    : Nothing
 *  Purpose    : Highlights the appropriate MenuBar Title.
 ****************************************************************************/
void MenuBar::highlightTitle(int index, int hcol = MB_HIL)
{
	int i, end;
	end = x[index] + strlen(Titles[index]) + 1;
	for ( i = x[index]; i < end; i++ )
		highlightChar(i, y[index], hcol);
}
/****************************************************************************
 *  Name       : inMenuBar
 *  Parameters : X position
 *               Y position
 *  Returns    : Returns Index of MenuBar Title on success else -1
 *  Purpose    : Checks if the coordinates are inside the MenuBar.
 ****************************************************************************/
int MenuBar::inMenuBar(int Xpos, int Ypos)
{
	int i;
	for ( i = 0; i < NoOfMenus; i++ )
	{
		if ( Xpos < (x[i] + strlen(Titles[i])) && Ypos <= y[i] )
			return i;
	}
	return -1;
}
/****************************************************************************
 *  Name       : addMenu
 *  Parameters : Index
 *               Pointer to a Menu
 *  Returns    : Nothing
 *  Purpose    : Adds a Menu to an existing MenuBar Title.
 ****************************************************************************/
void MenuBar::addMenu(int ID, Menu *mnu)
{
	if ( ID < NoOfMenus )
		MenuList[ID] = *mnu;
}
/****************************************************************************
 *  Name       : addMenu
 *  Parameters : Index
 *               Number of MenuItems
 *               String array containing the MenuItems
 *  Returns    : Nothing
 *  Purpose    : To create a Menu and add it to the MenuBar.
 ****************************************************************************/
void MenuBar::addMenu(int ID, int no, char **menuItems)
{
	if ( ID < NoOfMenus )
	MenuList[ID].createMenu(no, menuItems);
	//addMenu(ID, (new Menu(no, menuItems)));
}
/****************************************************************************
 *  Name       : showMenuBar
 *  Parameters : Index of the Menu
 *  Returns    : Nothing
 *  Purpose    : Shows the appropriate Menu according to the index.
 ****************************************************************************/
void MenuBar::showMenu(int ID)
{
	MenuList[ID].showMenu();
}
/****************************************************************************
 *  Name       : notifyAll
 *  Parameters : None
 *  Returns    : Nothing
 *  Purpose    : Notifies the MenuBar to initialize its positional
 *               members and notify all the Menus it contains.
 ****************************************************************************/
void MenuBar::notifyAll()
{
	/*
	 * Notifies the Menu Bar to notify all the menus
	 *   * Must be called before any MenuBar function can be called
	 */
	int i;
	for ( i = 0; i < NoOfMenus; i++ )
	{
		MenuList[i].setXY(x[i], y[i] + 1);
		MenuList[i].notify();
		//MenuWindow[i] = (int *) malloc(8);
		MenuList[i].getMenuCoords(&MenuRect[i]);
	}
}
/****************************************************************************
 *  Name       : showMenuBar
 *  Parameters : None
 *  Returns    : Nothing
 *  Purpose    : Displays the MenuBar.
 ****************************************************************************/
void MenuBar::showMenuBar()
{
	int i;
	for ( i = 0; i < 80; i++ )
		putChar(i, 0, ' ', MB_TXT);
	for (i = 0; i < NoOfMenus; i++ )
		putStr(x[i] + 1, y[i], Titles[i], MB_TXT, MB_HOT);
}
/****************************************************************************
 *  Name       : handleMenuBar
 *  Parameters : Index of Title
 *  Returns    : An integer with its high byte containing the selected
 *               MenuBar index and the low byte containing the index of
 *               the selected MenuItem
 *  Purpose    : Handles the MenuBar events.
 ****************************************************************************/
int MenuBar::handleMenuBar(int key)
{
	int mbExit = 0, ch, choice, OldKey;
	char *screen;

	while ( !mbExit )
	{
		highlightTitle(key);
		if ( kbhit() )
		{
			ch = getKey();
			switch ( ch )
			{
				case  DOWN:
				case ENTER: screen = saveRect(MenuRect[key]);
										MenuList[key].showMenu();
										choice = MenuList[key].handleMenu();
										restoreRect(MenuRect[key], screen);
										highlightTitle(key, MB_TXT >> 4);
										if ( choice == RIGHT || choice == LEFT )
										{
											highlightTitle(key, MB_TXT >> 4);
											key = (choice == RIGHT) ? ((key == (NoOfMenus-1)) ? 0 : ++key)
																							: ((key == 0) ? (NoOfMenus-1) : --key);
											highlightTitle(key);
											choice = -1;
										}
										if ( choice != -1 )
											return (((key & 0xff) << 8) + choice);
										break;
				case RIGHT: highlightTitle(key, MB_TXT >> 4);
										key = (key == (NoOfMenus-1)) ? 0 : ++key;
										highlightTitle(key);
										break;
				case  LEFT: highlightTitle(key, MB_TXT >> 4);
										key = (key == 0) ? (NoOfMenus-1) : --key;
										highlightTitle(key);
										break;
				case   ESC: highlightTitle(key, MB_TXT >> 4);
										mbExit = 1;
										break;
			}
		}
	}
	return -1;
}
